<?php
/**
 * @purpose  计算编辑行程产生的价格差
 * @Author   : Madou
 * @Time     : 2022/8/2 17:56
 */

namespace App\Trip\Orders\BookOrders\TaskEdit;

// 编辑任务支付信息
use App\Models\Trip\TripOrderCosts\Repositories\Interfaces\TripOrderCostsRepositoryInterface;
use Exception;
use Illuminate\Support\Collection;

class TaskEditPayData
{

    private TaskEditOrder $edit_order;
    /**
     * @var  TripOrderCostsRepositoryInterface
     */
    private TripOrderCostsRepositoryInterface $costRepo;
    private Collection                        $before_tickets_price_details;
    private Collection                        $after_tickets_price_details;

    /**
     * @throws Exception
     */
    public function __construct(TaskEditOrder $taskEditOrder)
    {
        $this->edit_order                   = $taskEditOrder;
        $this->costRepo                     = app(TripOrderCostsRepositoryInterface::class);
        $this->before_tickets_price_details = $this->costRepo->getOrderPassengersTicketCosts($taskEditOrder->getTaskInfo()->getTrainOrderInfo());
        $this->after_tickets_price_details  = $taskEditOrder->getOrderBuilder()->priceDetailsBuilder()->getPriceDetails4Ticket();
    }

    // 修改前的票价明细 可能处在 0次至n次编辑差价
    public function getBeforeTicketsPriceDetails(): Collection
    {
        return $this->before_tickets_price_details;
    }

    // 修改后的票价明细 含儿童票 和成人票等 , 新构造时 不会有编辑任务的标价 修改前可能会有
    public function getAfterTicketsPriceDetails(): Collection
    {
        return $this->after_tickets_price_details;
    }

    /**
     * @throws Exception
     */
    public function getAfterOrderAmount(): float
    {
        return $this->getBeforeOrderAmount() + $this->getNeedPayAmount();
    }

    /**
     * 修改前的订单金额
     *
     * @return float
     * @throws Exception
     */
    public function getBeforeOrderAmount(): float
    {
        return $this->edit_order->getTaskInfo()->getTrainOrderInfo()->getReceivable();
    }

    /**
     * 需要支付的金额
     *
     * @return float
     * @throws Exception
     */
    public function getNeedPayAmount(): float
    {
        $after  = $this->getAfterTicketsPrice();
        $before = $this->getBeforeTicketsPrice();
        if ($after < $before) {
            throw new Exception("编辑失败,原行程数据不可更改");
        }

        return $after - $before;
    }

    public function getAfterTicketsPrice(): float
    {
        return $this->after_tickets_price_details
            ->sum(fn($detail) => $detail['count'] * $detail['price']);
    }

    public function getBeforeTicketsPrice(): float
    {
        return $this->before_tickets_price_details
            ->sum(fn($detail) => $detail['count'] * $detail['price']);
    }

    public function getTripDataUniqueKey(): string
    {
        return $this->edit_order->getEditTripKey();
    }

    public function getTripDataJson(): string
    {
        return json_encode($this->edit_order->getParam()->getParams(), JSON_UNESCAPED_UNICODE) ?: '';
    }
}